package com.hongxun.design.utils.socketutil;

import android.os.Handler;

import com.alibaba.fastjson.JSON;
import com.hongxun.design.MyApp;
import com.hongxun.design.bean.ProjectItemBean;
import com.hongxun.design.bean.ScanHotBean;
import com.hongxun.design.bean.service.MessageData;
import com.hongxun.design.mytools.MString;
import com.hongxun.design.mytools.MyLog;
import com.hongxun.design.object_properties.MyMessage;
import com.hongxun.design.utils.fastjson.FastJsonUtil;

import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;


/**
 * Created by zerdoor_pc on 2016/4/22.
 */
public class LongWriterAndReader {
    public static boolean flag = true;

    public synchronized static void writer(OutputStream pw, MessageData data, boolean canSend) throws IOException {
        canSend = false;
        if (data == null) return;
        MyLog.L(MString.service + "发送消息2");
        String msg = data.getMsg();
        String name = data.getName();
        int type = data.getDataType();
        DataOutputStream out = new DataOutputStream(pw);
        switch (type) {
            case 1:
                sendText(out, msg);
                break;
            case 2:
                sendImage(out, msg);
                break;
            case 3:
                sendVoice(out, msg);
                break;
            case 4:
                if (name.length() != 0) {
                    sendFile(out, msg, name);
                } else {
                    MyLog.L(MString.service + "文件名不能为空");
                }
                break;
        }
        data = null;
        MyLog.L(MString.service + "发送消息成功");
        canSend = true;
    }

    public synchronized static void writer(OutputStream pw, int data, Boolean cansend) throws IOException {

        if (data == 0 && cansend) {
            MyLog.L(MString.service_heart + "发送0");
            DataOutputStream out = new DataOutputStream(pw);
            out.writeInt(data);
            out.flush();
        }

    }

    private static void sendText(DataOutputStream out, String msg) throws IOException {
        MyLog.L(MString.service + ": sendText");
        out.writeInt(1);
        out.writeInt(msg.getBytes("utf-8").length);
//        out.writeLong(msg.getBytes().length);
        out.write(msg.getBytes("utf-8"));
        out.flush();
    }

    private static void sendImage(DataOutputStream out, String path) throws IOException {
        MyLog.L(MString.service + ": sendImage");
        out.writeInt(2);
        FileInputStream fileInput = new FileInputStream(path);
//        out.writeLong(fileInput.available());
        out.writeInt(fileInput.available());
        int size = -1;
        byte[] buffer = new byte[1024];
        while ((size = fileInput.read(buffer, 0, 1024)) != -1) {
            out.write(buffer, 0, size);
        }
        out.flush();
    }

    private static void sendVoice(DataOutputStream out, String path) throws IOException {
        MyLog.L(MString.service + ": sendVoice");
        out.writeInt(3);
        FileInputStream fileInput = new FileInputStream(path);
//        out.writeLong(fileInput.available());
        out.writeInt(fileInput.available());
        int size = -1;
        byte[] buffer = new byte[1024];
        while ((size = fileInput.read(buffer, 0, 1024)) != -1) {
            out.write(buffer, 0, size);
        }
        out.flush();
    }

    private synchronized static void sendFile(DataOutputStream out, String path, String name) throws IOException {
        MyLog.L(MString.service + ": sendFile" + out.size());
        out.writeInt(4);//文件类型
        MyLog.L("out:发送In—"+4);
        FileInputStream fileInput = new FileInputStream(path);
//        out.writeLong(fileInput.available());//文件长度
        out.writeInt(fileInput.available());//文件长度
        MyLog.L("out:发送In—"+fileInput.available());
        out.writeInt(name.getBytes("utf-8").length);//文件名长度
        MyLog.L("out:发送In—"+name.getBytes("utf-8").length);
        out.write(name.getBytes("utf-8"));
        MyLog.L("out:发送 —"+name.getBytes("utf-8"));
        int size = -1;
        byte[] buffer = new byte[1024];
        while ((size = fileInput.read(buffer, 0, 1024)) != -1) {
            out.write(buffer, 0, size);
            MyLog.L("out:发送 file—"+ JSON.toJSONString(buffer));
        }
        out.flush();
        MyLog.L(MString.service + ":end" + out.size());

    }

    /**
     * 正式读取
     **/
    public synchronized static String reader(InputStream inputStream, boolean isbig, Boolean cansend, Handler handler) throws IOException {

        if (inputStream.available() != 0) {
            MyLog.L(MString.service + "读取1start_________________________ inputStream=" + inputStream.available());
        }
        int temp = -1;
        // MyLog.L(MString.service + "读取消息2isbig1=" + isbig);
        if (inputStream.available() == 0) {
            return "-1";
        }
        if (inputStream.available() > 1000) {
            MyLog.L(MString.service + "读取1start_________________________ ");
        }
        int type = readByte(inputStream, isbig, 4, temp, 0, 4);//解析类型
        MyLog.L(MString.service + "读取消息3type=" + type + " inputStream=" + inputStream.available());
        if (type == 0) {
            if (inputStream.available() == 4) {
                type = readByte(inputStream, isbig, 4, temp, 0, 4);//解析类型
            }
            MyLog.L(MString.service + "读取消息3type=" + type + " available=" + inputStream.available() + " inputStream=" + inputStream);
            if (inputStream.available() > 10) {
//                if (inputStream.available() > 100) {
                    reader(inputStream, isbig, cansend, handler);
//                }
//                byte[] buffer = new byte[inputStream.available()];
//                int size = -1;
//                long length = 0;
//                while ((size = inputStream.read(buffer)) != 0) {
//                    length += size;
//                    MyLog.L(MString.service2 + "length==" + length);
//                    MyLog.L(MString.service2 + "size==" + size);
//                    try {
//                        MyLog.L(MString.service + "读取到消息 message=" + new String(buffer, "utf-8"));
//                    } catch (Exception e) {
//                        MyLog.L(MString.service2 + "读取消息循环异常:no exists" + e.toString());
//                    }
//                }
            }

            return "0";
        }
        if (type > 4) {
            MyLog.L(MString.service + "读取消息4nowType=" + nowType);
            if (nowType <= 4 && nowType > 0) type = nowType;
            isbig = !isbig;
        }
        MyLog.L(MString.service + "读取消息5type=" + type);
        if (type > 4 || type <= 0) {
            return "0";
        }

        MyLog.L(MString.service + "读取消息6type=" + type);
        String s = "-1";
        if (type == 4 && !cansend) {
            cansend = true;
            if (handler != null) handler.sendMessage(MyMessage.getMessage(200, -2, -2, "0"));
            return "0";
        }

        if (isbig) {
            //Android 读取
            MyLog.L(MString.service + "  DataType：" + type);
            s = ReciveAndSend.reciveMsg(inputStream, type, handler);
        } else {
            //ios读取
            MyLog.L(MString.service + "读取消息4isbig2=" + isbig);
//            long fileLength = readByteToLong(inputStream, isbig, 8, temp, 0, 8);//解析文件长度

            long fileLength = readByte(inputStream, isbig, 4, temp, 0, 4);//解析文件长度
            MyLog.L(MString.service + "读取消息fileLength=" + fileLength);
            String name = "";
            if (type == 4) {
                int nameLength = readByte(inputStream, isbig, 4, temp, 0, 4);//解析文件名长度
                name = readByteToString(inputStream, isbig, nameLength, temp, 0, nameLength);//解析文件名
            }
            switch (type) {
                case 1:
                    byte[] buffer = new byte[(int) fileLength];
                    MyLog.L(MString.service + "解析文件：temp==" + temp);
                    temp = inputStream.read(buffer);
                    s = new String(buffer, 0, (int) fileLength);
                    MyLog.L(MString.service + "解析文件：temp==" + temp + s);
                    MyLog.L(MString.service + "解析文件：inputStream" + inputStream.available());

                    if (inputStream.available() > 100) {
                        addProject( s,  cansend,handler);
                        reader(inputStream, isbig, cansend, handler);
                    }
                    break;
                case 2:
                    break;
                case 3:
                    break;
                case 4:
                    readByteToFile(inputStream, isbig, fileLength, temp, 0, fileLength, name, handler);
                    break;
            }


        }
        MyLog.L(MString.service + "读取end_________________________");
        nowType = 0;

        return s;


    }

    private synchronized static void addProject(String s,boolean isrecive, Handler handler){
        if (s.length() > 0 && !s.equals("0") && !s.equals("-1")) {
            ScanHotBean bean = FastJsonUtil.getScanHotBean(s);
            MyLog.L(MString.service + "  接收消息s:" + s);
            if (bean.getMessageType().equals(MString.userInfo)) {

            } else if (bean.getMessageType().equals(MString.projectInfo)) {
                //handler.sendEmptyMessage(3);//接收模式
                ProjectItemBean b = FastJsonUtil.JsonToGetProject(bean.getMessage());
                handler.sendMessage(MyMessage.getMessage(3, 0, 0, b.getProject_name()));
                isrecive = MyApp.File.saveProjectList(bean.getMessage()) ;//存储项目信息
            }
        }
    }

    /**
     * demo
     **/
    public synchronized static String reader(InputStream inputStream, Boolean isbig, Boolean cansend) throws IOException {

        MyLog.L(MString.service_heart + "读取start_________________________");
        int temp = -1;
        // MyLog.L(MString.service_heart + "读取消息isbig1=" + isbig);
        if (inputStream.available() == 0) {
            return "-1";
        }
        int type = readByte(inputStream, isbig, 4, temp, 0, 4);//解析类型
        MyLog.L(MString.service_heart + "读取消息type=" + type);
        if (type == 0) {
            return "0";
        }
        if (type > 4) {
            MyLog.L(MString.service + "读取消息nowType=" + nowType);
            if (nowType <= 4 && nowType > 0) type = nowType;
            isbig = !isbig;
        }
        MyLog.L(MString.service + "读取消息type=" + type);
        if (type > 4 || type <= 0) {
            return "0";
        }

        MyLog.L(MString.service + "读取消息type=" + type);
        String s = "-1";
        if (isbig) {
            //Android 读取
//            int DataType = dins.readInt();
            MyLog.L(MString.service + "  DataType：" + type);
            s = ReciveAndSend.reciveMsg(inputStream, type);
        } else {
            //ios读取
            MyLog.L(MString.service + " 读取消息isbig2=" + isbig);
            long fileLength = readByteToLong(inputStream, isbig, 8, temp, 0, 8);//解析文件长度
            String name = "";
            if (type == 4) {
                int nameLength = readByte(inputStream, isbig, 4, temp, 0, 4);//解析文件名长度
                name = readByteToString(inputStream, isbig, nameLength, temp, 0, nameLength);//解析文件名
            }
            switch (type) {
                case 1:
                    byte[] buffer = new byte[(int) fileLength];
                    MyLog.L(MString.service + "解析文件：temp==" + temp);
                    temp = inputStream.read(buffer);
                    s = new String(buffer, 0, (int) fileLength);
                    MyLog.L(MString.service + "解析文件：temp==" + temp + s);
                    MyLog.L(MString.service + "解析文件：inputStream" + inputStream.available());
                    break;
                case 2:
                    break;
                case 3:
                    break;
                case 4:
                    readByteToFile(inputStream, isbig, fileLength, temp, 0, fileLength, name, null);
                    break;
            }


        }
        MyLog.L(MString.service + "读取end_________________________");
        nowType = 0;

        return s;


    }

    private static int nowType = 0;

    /**
     * 解析类型*
     */
    private static int readByte(InputStream inputStream, Boolean isbig, int length, int temp, int first, int end) throws IOException {
        byte[] buffer = new byte[length];
        int type = -1;
        if ((temp = inputStream.read(buffer)) != -1) {

            type = bytes2Int(buffer, first, end, isbig);

            if (type == 0 && inputStream.available() > 0)
                nowType = bytes2Int(buffer, first, end, !isbig);

            if (type > 4) nowType = bytes2Int(buffer, first, end, !isbig);

            MyLog.L(MString.service + "解析Int：" + type);//类型
            MyLog.L(MString.service + "解析Int2：" + nowType);//类型
        }
        return type;
    }

    /**
     * 解析长度*
     */
    private static long readByteToLong(InputStream inputStream, Boolean isbig, int length, int temp, int first, int end) throws IOException {
        byte[] buffer = new byte[length];
        long size = -1;
        if ((temp = inputStream.read(buffer)) != -1) {
            size = bytes2Long(buffer, first, end, isbig);
            MyLog.L(MString.service + "解析Long：" + size);//类型
        }
        return size;
    }

    /**
     * 解析字符串*
     */
    private static String readByteToString(InputStream inputStream, Boolean isbig, int length, int temp, int first, int end) throws IOException {
        byte[] buffer = new byte[length];
        String s = "";
        if ((temp = inputStream.read(buffer)) != -1) {
            s = new String(buffer, first, end);
            MyLog.L(MString.service + "解析Long：" + s);//类型
        }
        return s;
    }

    /**
     * 解析文件*
     */
    private static void readByteToFile(InputStream inputStream, Boolean isbig, long length, int temp, int first, long end, String name, Handler handler) throws IOException {

        MyLog.L(MString.service + ": savename=" + name);
        MyLog.L(MString.service + "解析文件：temp==" + temp);
        ReciveAndSend.saveBitmap(inputStream, name, length, handler);
        MyLog.L(MString.service + "解析文件：inputStream" + inputStream.available());
    }


    private static int bytes2Int(byte[] bys, int start, int len,
                                 boolean isBigEndian) {
        int num = 0;
        for (int i = start, k = start + len % (Integer.SIZE / Byte.SIZE + 1); i < k; i++) {
            num |= (bys[i] & 0xff) << ((isBigEndian ? (k - i - 1) : i) * Byte.SIZE);
        }
        return num;
    }

    private static Long bytes2Long(byte[] bys, int start, int len,
                                   boolean isBigEndian) {
        long num = 0;
        for (int i = start, k = start + len % (Integer.SIZE / Byte.SIZE + 1); i < k; i++) {
            num |= (bys[i] & 0xff) << ((isBigEndian ? (k - i - 1) : i) * Byte.SIZE);
        }
        return num;
    }
}
